<template>
    <div class="p-painter" @mousewheel.prevent @onmousewheel.prevent @DOMMouseScroll.prevent>
        <v-canvas-grid
            :mode="mode"
            :map="currentMap"
            @mapChange="v => (currentMap = v)"
            ref="vCanvasGrid"
            :coordinateScope="currentCoordinateScope"
            :scalingScope="currentScalingScope"
            :draggable="dragEnable"
            :scalingable="scalingable"
            :multiSelectable="isMultiSelectActive"
            :dimensions="currentDimensions"
            :rulerMode="rulerMode"
            :disableRuler="disableRuler"
            showCompass
            :showPanic="isPanicActive"
            :clickFunc="clickFunc"
            :pointerDownFunc="pointerDownFunc"
            :pointerUpFunc="pointerUpFunc"
            :pointerLeaveFunc="pointerLeaveFunc"
            :pointerMoveFunc="pointerMoveFunc"
            :tapFunc="tapFunc"
            :panFunc="panFunc"
        >
            <p-painter-contours
                :mode="mode"
                :map="currentMap"
                :hideContours="hideContours"
                :hideRanges="hideRanges"
                ref="pContours"
                :tapeMode="tapeMode"
                @dimensionsChange="dimensionsChange"
                @drawContours="handleDrawContours"
                @drawRanges="handleDrawRanges"
                @contoursChange="ids => emitChange('contours', ids)"
                @rangesChange="ids => emitChange('ranges', ids)"
            ></p-painter-contours>
            <p-painter-paths
                v-if="!hidePaths"
                :mode="mode"
                :map="currentMap"
                :hidePaths="hidePaths"
                ref="pPaths"
                @dimensionsChange="dimensionsChange"
                @drawPaths="handleDrawPaths"
                @pathsChange="ids => emitChange('paths', ids)"
                @bezierChanged="ps => $emit('bezierChanged', ps)"
            ></p-painter-paths>
            <p-painter-vehicles
                v-if="!hideVehicles"
                :mode="mode"
                :map="currentMap"
                :hideVehicles="hideVehicles"
                ref="pVehicles"
                :displayVehicleLabels="displayVehicleLabels"
                @draggableChange="v => (currentDraggable = v)"
                @dimensionsChange="dimensionsChange"
                @quickJob="handleQuickJob"
                @vehiclesChange="ids => emitChange('vehicles', ids)"
            ></p-painter-vehicles>
            <!-- <v-canvas-painter ref="vCanvasPainter" :map="currentMap"></v-canvas-painter> -->
        </v-canvas-grid>
        <slot></slot>
    </div>
</template>

<script>
import * as enums from '../store/status-enums.js';
import * as Matrix from '../utils/Matrix.js';
import * as Expert from '../utils/Expert.js';
import { mapState } from 'vuex';
import bus from '../utils/Eventbus.js';
import Point from '../utils/Point.js';
import Kernel from '../core/Kernel.js';
import vCanvasGrid from '../utils/v-canvas-grid.vue';
import pPainterContours from './p-painter-contours.vue';
import pPainterPaths from './p-painter-paths.vue';
import pPainterVehicles from './p-painter-vehicles.vue';
import * as Utils from '../core/utils.js';
// import EventsWorker from '../../workers/events.worker.js';

/**
 * p-painter
 */
export default {
    name: 'p-painter',
    components: { vCanvasGrid, pPainterContours, pPainterPaths, pPainterVehicles }, //eslint-disable-line
    props: {
        // display mode of the map, can be '2d' or 'isometric', default is '', means '2d', maybe '3d' in the future.
        mode: {
            type: String,
            default: ''
        },
        dimensions: Array,
        map: Object, // map arguments
        scalingable: {
            type: Boolean,
            default: true
        },
        draggable: {
            type: Boolean,
            default: true
        },
        tapeMode: Boolean,
        clickable: Boolean,
        rulerMode: Number,
        dragMode: Boolean,
        disableRuler: Boolean,
        displayVehicleLabels: Boolean,
        // coordinates scope, same as dimensions: 'auto' or [minX, maxX, minY, maxY]
        coordinateScope: [String, Array],
        // scaling scope: 'auto' or [min, max]
        scalingScope: [String, Array],
        vehiclesSelectable: {
            type: Boolean,
            default: false
        },
        pathsSelectable: {
            type: Boolean,
            default: false
        },
        contoursSelectable: {
            type: Boolean,
            default: false
        },
        rangesSelectable: {
            type: Boolean,
            default: false
        },
        hideVehicles: {
            type: Boolean,
            default: false
        },
        hidePaths: {
            type: Boolean,
            default: false
        },
        hideContours: {
            type: Boolean,
            default: false
        },
        hideRanges: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            currentMap: this.map,
            trueName: this.$options.name,
            currentCoordinateScope: null,
            currentScalingScope: null,
            // dimensions: null, // [-10000, 10000, -10000, 10000],
            currentDimensions: this.dimensions, // [-10000, 10000, -10000, 10000],
            currentDraggable: this.draggable
        };
    },
    computed: {
        ...mapState({
            openedBoxes: state => state.businessStatus.openedBoxes,
            selectedContours: state => state.businessStatus.selectedContours,
            selectedRanges: state => state.businessStatus.selectedRanges,
            selectedPaths: state => state.businessStatus.selectedPaths,
            selectedVehicles: state => state.businessStatus.selectedVehicles,
            isDrawContoursActive: state => state.businessStatus.isDrawContoursActive,
            isDrawRangesActive: state => state.businessStatus.isDrawRangesActive,
            isDrawPathsActive: state => state.businessStatus.isDrawPathsActive,
            isMultiSelectActive: state => state.businessStatus.isMultiSelectActive,
            isAltFnActive: state => state.businessStatus.isAltFnActive,
            isPanicActive: state => state.businessStatus.isPanicActive,
            isHelperActive: state => state.businessStatus.isHelperActive,
            isAllData: state => state.businessStatus.isAllData
        }),
        dragEnable() {
            // return (
            //     this.currentDraggable &&
            //     !this.isDrawContoursActive &&
            //     !this.isDrawRangesActive &&
            //     !this.isDrawPathsActive &&
            //     !this.isMultiSelectActive
            // );
            return this.currentDraggable;
        }
    },
    watch: {
        map(val) {
            this.currentMap = val;
        },
        currentMap: {
            handler(val) {
                this.$emit('mapChange', val);
            },
            deep: true
        },
        draggable(val) {
            this.currentDraggable = val;
        },
        dimensions(val) {
            this.currentDimensions = val;
        },
        coordinateScope: {
            handler() {
                this.initCoordinateScope();
            },
            immediate: true,
            deep: true
        },
        scalingScope: {
            handler() {
                this.initScalingScope();
            },
            immediate: true,
            deep: true
        },
        isHelperActive(val) {
            if (val) return;
            window.setTimeout(() => {
                this.$refs.vCanvasGrid.init();
            }, 400);
        },
        hideVehicles(val) {
            console.log('p-paniter.watch.hideVehicle:', val);
            // bus.emit('p-painter-paths.refresh', true);
        },
        hidePaths(val) {
            console.log('p-paniter.watch.hidePaths:', val);
            // bus.emit('p-painter-paths.refresh', true);
        }
        // isDrawContoursActive(val) {
        //     if (!val && this.$refs.pContours.localList && this.$refs.pContours.localList.length) {
        //         console.warn('p-painter.watch.isDrawContoursActive: ', this.$refs.pContours.localList);
        //     }
        // }
    },
    created() {
        bus.on(`${this.trueName}.repaint`, this.repaint);
        bus.on(`${this.trueName}.clearLocals`, this.clearLocals);
        bus.on(`${this.trueName}.saveCurrentMapDimensions`, this.saveCurrentMapDimensions);
        bus.on(`${this.trueName}.updateCurrentMapDimensions`, this.updateCurrentMapDimensions);
        bus.on(`${this.trueName}.dimensionsChange`, this.dimensionsChange);
        bus.on(`${this.trueName}.initDimensions`, this.initDimensions);
    },
    unmounted: function() {
        // if (this.worker) this.worker.terminate();
        // 清除事件监听
        bus.off(`${this.trueName}.repaint`, this.repaint);
        bus.off(`${this.trueName}.clearLocals`, this.clearLocals);
        bus.off(`${this.trueName}.saveCurrentMapDimensions`, this.saveCurrentMapDimensions);
        bus.off(`${this.trueName}.updateCurrentMapDimensions`, this.updateCurrentMapDimensions);
        bus.off(`${this.trueName}.dimensionsChange`, this.dimensionsChange);
        bus.off(`${this.trueName}.initDimensions`, this.initDimensions);
        this.stop();
    },
    mounted() {
        this.init();
    },
    methods: {
        init() {
            // // 初始化webworker计算到底点了什么
            // this.worker = new EventsWorker();
            // this.worker.onmessage = res => this.finallyClick.call(this, res);
            // console.log('p-painter.init: ', this._uid, this.currentDimensions);
            /**
             * App.vue handleResourcesFunc 数据返回全量时，isAllData 标识为true
             * 1、initDimensions
             * 2、initCoordinateScope
             * 3、initScalingScope
             * 4、start
             */
            if (!this.maxTry) this.maxTry = 1;
            if (!this.isAllData && this.maxTry < 100) {
                this.maxTry++;
                return setTimeout(this.init.bind(this), 200);
            } else {
                this.maxTry = 0;
                this.initDimensions();
                this.initCoordinateScope();
                this.initScalingScope();
                this.start();
            }
            // this.start();
        },
        initDimensions() {
            // console.error('initDimensions', this.$root.resources);
            if (this.currentDimensions && this.currentDimensions.length) return;
            let pd = Matrix.getPathDimensions(this.$root.resources.paths),
                cd = Matrix.getContourDimensions(this.$root.resources.contours, pd),
                rd = Matrix.getContourDimensions(this.$root.resources.ranges, cd);
            this.currentDimensions = rd;
            // if (this.$root.resources.paths && this.$root.resources.paths.length) {
            //     this.currentDimensions = Matrix.getContourDimensions(this.$root.resources.contours || []);
            //     // console.log('p-painter.init: ---> ', this._uid, this.currentDimensions, this.$refs.vCanvasGrid.ratio);
            // }
        },
        initCoordinateScope() {
            if (!this.currentDimensions || !this.currentDimensions.length) return;
            if (!this.coordinateScope) this.currentCoordinateScope = undefined;
            else if (typeof this.coordinateScope === 'string' && this.coordinateScope === 'auto') {
                this.$nextTick(() => {
                    this.currentCoordinateScope = this.currentDimensions.concat();
                    console.log('p-painter.initCoordinateScope: ', this.currentCoordinateScope);
                });
            } else if (Array.isArray(this.coordinateScope) && this.coordinateScope.length) {
                this.currentCoordinateScope = this.coordinateScope;
            }
        },
        initScalingScope() {
            if (!this.scalingScope) this.currentScalingScope = undefined;
            else if (typeof this.scalingScope === 'string' && this.scalingScope === 'auto') {
                // after v-canvas-grid caculate Matrix.
                this.$nextTick(() => {
                    this.currentScalingScope = [this.map.scaling, 1];
                    console.log('p-painter.initScalingScope: ', this.currentScalingScope);
                });
            } else if (Array.isArray(this.scalingScope) && this.scalingScope.length) {
                this.currentScalingScope = this.scalingScope;
            }
        },

        // life cycle methods
        start() {
            this.stop();
            this.timer = requestAnimationFrame(this.runing);
        },
        runing() {
            this.stop();
            let kn = Kernel.getInstance(),
                pool = kn.updatesPool;
            if (kn.currentPage !== this.$route.name) {
                kn.updatesPool.push({ contours: true, paths: true, vehicles: true });
                kn.currentPage = this.$route.name;
            }
            // if (!pool || !pool.length) return (this.timer = requestAnimationFrame(this.runing));
            let p = (pool || []).shift();
            // console.log('p-painter.runing: ', p, pool);
            if (this.$refs.vCanvasGrid && typeof this.$refs.vCanvasGrid.refresh === 'function')
                this.$refs.vCanvasGrid.refresh(p);
            if (this.$refs.pContours && typeof this.$refs.pContours.refresh === 'function')
                this.$refs.pContours.refresh(p && (p.contours || p.ranges));
            // if (this.$refs.pPaths && typeof this.$refs.pPaths.refresh === 'function')
            //     this.$refs.pPaths.refresh((p && p.paths) || (p && p.jobs));
            if (this.$refs.pPaths && typeof this.$refs.pPaths.refresh === 'function')
                this.$refs.pPaths.refresh(p && p.paths);
            if (this.$refs.pVehicles && typeof this.$refs.pVehicles.refresh === 'function')
                this.$refs.pVehicles.refresh(p && p.vehicles);
            this.timer = requestAnimationFrame(this.runing);
            // if (img && !updatedTag && this.delayRenderNum > 10) {
            //     this.dynamicRender();
            //     return (this.refreshing = false);
            // }
        },
        stop() {
            if (this.timer) cancelAnimationFrame(this.timer);
        },
        saveCurrentMapDimensions(name) {
            // console.log('p-painter.saveCurrentMapDimensions.name:', name);
            let vCanvasGrid = this.$refs.vCanvasGrid,
                canvasMaxX = vCanvasGrid.$refs.canvas.width,
                canvasMaxY = vCanvasGrid.$refs.canvas.height,
                canvasRatio = vCanvasGrid.$data.ratio;
            // console.log('p-painter.saveCurrentMapDimensions.canvasRatio:', canvasRatio);
            let p0 = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, {
                x: 0,
                y: canvasMaxY
            });
            let p1 = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, {
                x: canvasMaxX,
                y: 0
            });
            // console.log('p-painter.saveCurrentMapDimensions.p0,p1', p0, p1);
            let d = Matrix.getCurrentMapDimensions(p0, p1, null, canvasRatio);
            let currentMabLabel = { name: name, dimensions: d };
            // console.log('p-painter.saveCurrentMapDimensions.currentMabLabel', currentMabLabel);
            let local = Utils.getLocalStorage('LOCAL_MAP_LABELS');
            let mapLabels = local.get('mapLabels') || [];
            mapLabels.push(currentMabLabel);
            local.set('mapLabels', mapLabels);
        },
        updateCurrentMapDimensions(position) {
            // console.log('p-painter.updateCurrentMapDimensions.position:', position);
            let vCanvasGrid = this.$refs.vCanvasGrid,
                canvasMaxX = vCanvasGrid.$refs.canvas.width,
                canvasMaxY = vCanvasGrid.$refs.canvas.height,
                canvasRatio = vCanvasGrid.$data.ratio;
            // console.log('p-painter.updateCurrentMapDimensions.canvasRatio:', canvasRatio);
            let p0 = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, {
                x: 0,
                y: canvasMaxY
            });
            let p1 = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, {
                x: canvasMaxX,
                y: 0
            });
            // console.log('p-painter.updateCurrentMapDimensions.p0,p1', p0, p1);
            let d = Matrix.getCurrentMapDimensions(p0, p1, null, canvasRatio);
            // console.log('p-painter.updateCurrentMapDimensions.dimensions', d);
            let local = Utils.getLocalStorage('LOCAL_MAP_LABELS');
            let mapLabels = local.get('mapLabels') || [];
            if (mapLabels.length > position) mapLabels[position].dimensions = d;
            // else mapLabels.push(currentMabLabel);
            local.set('mapLabels', mapLabels);
        },
        repaint(recalculate = false) {
            if (recalculate) {
                //
            } else {
                this.currentDimensions = null;
            }
            // if (!this.isHelperActive) this.delayRenderNum = 0;
            this.stop();
            Kernel.getInstance().updatesPool.push({ contours: true, paths: true, vehicles: true });
            this.init();
        },
        dimensionsChange(v) {
            if (v && v.length) this.currentDimensions = v;
            console.warn('p-painter.dimensionsChange: ', this._uid, v, this.currentDimensions);
        },
        clearLocals() {
            if (this.$refs.pContours && typeof this.$refs.pContours.clearLocals === 'function')
                this.$refs.pContours.clearLocals();
            if (this.$refs.pPaths && typeof this.$refs.pPaths.clearLocals === 'function')
                this.$refs.pPaths.clearLocals();
        },

        /**
         * hammer events
         */
        tapFunc(e) {
            if (!this.clickable || this.isDrawContoursActive || this.isDrawRangesActive || this.isDrawPathsActive)
                return;
            // console.error(e);
            let vCanvasGrid = this.$refs.vCanvasGrid,
                cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio),
                transPos = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, cursorPos);
            console.warn('p-painter.tapFunc: ', e, cursorPos);
            // console.error(cursorPos);
            let res = this.checkPointerClick({
                task: 'click',
                resources: this.$root.resources,
                cursorPos: cursorPos,
                transPos: transPos
            });
            this.finallyClick({ data: res });
        },
        panFunc(e) {
            if (!this.$refs || !Object.keys(this.$refs).length) return;
            let vCanvasGrid = this.$refs.vCanvasGrid;
            if (!vCanvasGrid || !Object.keys(vCanvasGrid.$refs).length) return;
            let cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio),
                transPos = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, cursorPos);
            // console.warn('p-painter.panFunc: ', e, cursorPos, transPos);
            if (this.dragMode && this.$refs.pVehicles && typeof this.$refs.pVehicles.pointerMoveFunc === 'function') {
                this.$refs.pVehicles.pointerMoveFunc(cursorPos, transPos);
            } else if (this.isMultiSelectActive && this.$refs.pContours && this.contoursSelectable) {
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('contoursTable') !== -1) {
                this.$refs.pContours.pointerMoveFunc(cursorPos, transPos);
            } else if (this.isMultiSelectActive && this.$refs.pPaths && this.pathsSelectable) {
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('pathsTable') !== -1) {
                this.$refs.pPaths.pointerMoveFunc(cursorPos, transPos);
            } else if (
                this.isDrawPathsActive &&
                this.$refs.pPaths &&
                typeof this.$refs.pPaths.pointerMoveFunc === 'function'
            ) {
                this.$refs.pPaths.pointerMoveFunc(cursorPos, transPos);
            }
        },

        /**
         * pointer events
         */
        pointerDownFunc(e) {
            this.pointerButton = e.button;
            if (this.pointerButton === 2) return;
            let vCanvasGrid = this.$refs.vCanvasGrid,
                cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio),
                transPos = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, cursorPos);
            this.startPoint = transPos;
            this.startTime = Date.now();
            if (this.dragMode && this.$refs.pVehicles && typeof this.$refs.pVehicles.pointerDownFunc === 'function') {
                // console.warn('p-painter.pointerDownFunc: drag vehicle...');
                this.$refs.pVehicles.pointerDownFunc(cursorPos, transPos);
                // } else if (this.isMultiSelectActive && this.contoursSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('contoursTable') !== -1) {
                //     this.$refs.pContours.pointerDownFunc(cursorPos, transPos);
                // } else if (this.isMultiSelectActive && this.rangesSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('rangesTable') !== -1) {
                //     this.$refs.pContours.pointerDownFunc(cursorPos, transPos, 'ranges');
                // } else if (this.isMultiSelectActive && this.pathsSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('pathsTable') !== -1) {
                //     this.$refs.pPaths.pointerDownFunc(cursorPos, transPos);
                // } else if (this.isDrawPathsActive && typeof this.$refs.pPaths.pointerDownFunc === 'function') {
                //     // console.warn('p-painter.pointerDownFunc: drawPaths...');
                //     this.$refs.pPaths.pointerDownFunc(cursorPos, transPos);
            } else if (
                this.contoursSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerDownFunc === 'function'
            ) {
                this.$refs.pContours.pointerDownFunc(cursorPos, transPos);
            } else if (
                this.rangesSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerDownFunc === 'function'
            ) {
                this.$refs.pContours.pointerDownFunc(cursorPos, transPos, 'ranges');
            } else if (
                this.pathsSelectable &&
                this.$refs.pPaths &&
                typeof this.$refs.pPaths.pointerDownFunc === 'function'
            ) {
                this.$refs.pPaths.pointerDownFunc(cursorPos, transPos);
            } else if (this.isMultiSelectActive && this.$refs.pVehicles && this.vehiclesSelectable) {
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('vehiclesTable') !== -1) {
                this.$refs.pVehicles.pointerDownFunc(cursorPos, transPos);
            }
            // else if (this.isDrawContoursActive && typeof this.$refs.pContours.pointerDownFunc === 'function') {
            //     // console.warn('p-painter.pointerDownFunc: drawContours...');
            //     this.$refs.pContours.pointerDownFunc(cursorPos, transPos);
            // } else if (this.isDrawRangesActive && typeof this.$refs.pContours.pointerDownFunc === 'function') {
            //     // console.warn('p-painter.pointerDownFunc: drawContours...');
            //     this.$refs.pContours.pointerDownFunc(cursorPos, transPos, 'ranges');
            // }
        },
        pointerMoveFunc(e) {
            if (!this.$refs || !Object.keys(this.$refs).length) return;
            // console.log('p-painter.pointerMoveFunc: ', this.$refs);
            let vCanvasGrid = this.$refs.vCanvasGrid;
            if (!vCanvasGrid || !Object.keys(vCanvasGrid.$refs).length) return;
            let cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio),
                transPos = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, cursorPos);
            if (this.dragMode && this.$refs.pVehicles && typeof this.$refs.pVehicles.pointerMoveFunc === 'function') {
                this.$refs.pVehicles.pointerMoveFunc(cursorPos, transPos);
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('contoursTable') !== -1) {
                //     this.$refs.pContours.pointerMoveFunc(cursorPos, transPos);
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('pathsTable') !== -1) {
                //     this.$refs.pPaths.pointerMoveFunc(cursorPos, transPos);
                // } else if (this.isDrawPathsActive && typeof this.$refs.pPaths.pointerMoveFunc === 'function') {
                //     this.$refs.pPaths.pointerMoveFunc(cursorPos, transPos);
            } else if (
                this.contoursSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerMoveFunc === 'function'
            ) {
                this.$refs.pContours.pointerMoveFunc(cursorPos, transPos);
            } else if (
                this.rangesSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerMoveFunc === 'function'
            ) {
                this.$refs.pContours.pointerMoveFunc(cursorPos, transPos, 'ranges');
            } else if (
                this.pathsSelectable &&
                this.$refs.pPaths &&
                typeof this.$refs.pPaths.pointerMoveFunc === 'function'
            ) {
                this.$refs.pPaths.pointerMoveFunc(cursorPos, transPos);
            }
        },
        pointerUpFunc(e) {
            this.pointerButton = -1;
            // console.log('p-painter.pointerUpFunc: ', this.pathsSelectable);
            let vCanvasGrid = this.$refs.vCanvasGrid,
                cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio);
            this.endpoint = Point.getInstanceByAnotherMatrix(this.currentMap.matrix, cursorPos);
            if (this.dragMode && this.$refs.pVehicles && typeof this.$refs.pVehicles.pointerUpFunc === 'function') {
                // console.warn('p-painter.pointerUpFunc: drag vehicle...');
                this.$refs.pVehicles.pointerUpFunc(cursorPos, this.endpoint);
                // } else if (this.isMultiSelectActive && this.contoursSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('contoursTable') !== -1) {
                //     this.$refs.pContours.pointerUpFunc(cursorPos, this.endpoint);
                // } else if (this.isMultiSelectActive && this.rangesSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('rangesTable') !== -1) {
                //     this.$refs.pContours.pointerUpFunc(cursorPos, this.endpoint, 'ranges');
                // } else if (this.isMultiSelectActive && this.pathsSelectable) {
                //     // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('pathsTable') !== -1) {
                //     this.$refs.pPaths.pointerUpFunc(cursorPos, this.endpoint);
                // } else if (this.isDrawPathsActive && typeof this.$refs.pPaths.pointerUpFunc === 'function') {
                //     // console.warn('p-painter.pointerUpFunc: drawPaths...');
                //     this.$refs.pPaths.pointerUpFunc(cursorPos, this.endpoint);
            } else if (
                this.contoursSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerUpFunc === 'function'
            ) {
                this.$refs.pContours.pointerUpFunc(cursorPos, this.endpoint);
            } else if (
                this.rangesSelectable &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerUpFunc === 'function'
            ) {
                this.$refs.pContours.pointerUpFunc(cursorPos, this.endpoint, 'ranges');
            } else if (
                this.pathsSelectable &&
                this.$refs.pPaths &&
                typeof this.$refs.pPaths.pointerUpFunc === 'function'
            ) {
                this.$refs.pPaths.pointerUpFunc(cursorPos, this.endpoint);
            } else if (this.isMultiSelectActive && this.vehiclesSelectable && this.$refs.pVehicles) {
                // } else if (this.isMultiSelectActive && this.openedBoxes.indexOf('vehiclesTable') !== -1) {
                this.$refs.pVehicles.pointerUpFunc(cursorPos, this.endpoint);
            }
            // else if (this.isDrawContoursActive && typeof this.$refs.pContours.pointerUpFunc === 'function') {
            //     // console.warn('p-painter.pointerUpFunc: drawContours...');
            //     this.$refs.pContours.pointerUpFunc(cursorPos, this.endpoint);
            // }
        },
        pointerLeaveFunc(e) {
            this.pointerButton = -1;
            // console.log('p-painter.pointerLeaveFunc: ', e);
            if (this.dragMode && typeof this.$refs.pPaths.pointerLeaveFunc === 'function') {
                this.$refs.pPaths.pointerLeaveFunc(e);
            } else if (
                this.tapeMode &&
                this.$refs.pContours &&
                typeof this.$refs.pContours.pointerLeaveFunc === 'function'
            ) {
                this.$refs.pContours.pointerLeaveFunc(e);
            } else if (
                this.dragMode &&
                this.$refs.pVehicles &&
                typeof this.$refs.pVehicles.pointerLeaveFunc === 'function'
            ) {
                console.warn('p-painter.pointerUpFunc: drag vehicle...');
                this.$refs.pVehicles.pointerLeaveFunc(e);
            }
        },

        // pointer events, from v-canvas-grid ...
        // clickHandler(op, tp) {
        //     console.log('p-painter.clickHandler: ', tp, this.worker);
        //     if (this.isDrawContoursActive && typeof this.$refs.pContours.pointerDownFunc === 'function') {
        //         // console.warn('p-painter.clickHandler: drawContours...');
        //         this.$refs.pContours.pointerDownFunc(op, tp);
        //     } else {
        //         this.worker.postMessage({ task: 'click', resources: this.$root.resources, point: tp });
        //         this.clickedPath = this.checkPathsByPoint(op, tp);
        //     }
        //     // console.log('p-painter.clickHandler: ', p, op, this.clickedPath);
        // },
        clickFunc(e) {
            if (!this.clickable || this.isDrawContoursActive || this.isDrawPathsActive) return;
            let vCanvasGrid = this.$refs.vCanvasGrid,
                cursorPos = Point.getInstanceByMouseOffset(e, vCanvasGrid.$refs.canvas, vCanvasGrid.$data.ratio);
            /**
             * 有时候当前时间会比开始时间大于120，会阻止选择路径和图形。现在改成200
             * @author slq
             * @date 2020.04.01
             */
            // if (Date.now() - this.startTime > 120 || this.endpoint.distance(this.startPoint) > 1) return;
            if (Date.now() - this.startTime > 200 || this.endpoint.distance(this.startPoint) > 1) return;
            // console.log('p-painter.click! ');
            // this.worker.postMessage({ task: 'click', resources: this.$root.resources, point: this.endpoint });
            // this.clickedPath = this.checkPathsByPoint(cursorPos, this.endpoint);
            let res = this.checkPointerClick({
                task: 'click',
                resources: this.$root.resources,
                cursorPos: cursorPos,
                transPos: this.endpoint
            });
            this.finallyClick({ data: res });
        },
        // check pointer when clicked
        checkPointerClick(res) {
            console.log('p-painter.checkPointerClick: ', res);
            let obj = this.checkVehicles(res.transPos, res.resources.vehicles);
            if (obj) return { task: 'click', resourcesType: 'vehicles', resourcesId: obj.id, resourcesIdx: -1 };

            obj = this.checkPaths(res.cursorPos, res.resources.paths);
            if (obj) return { task: 'click', resourcesType: 'paths', resourcesId: obj.id, resourcesIdx: -1 };

            obj = this.checkContours(res.cursorPos, res.resources.contours);
            if (obj) return { task: 'click', resourcesType: 'contours', resourcesId: obj.id, resourcesIdx: -1 };

            obj = this.checkRanges(res.cursorPos, res.resources.ranges);
            if (obj) return { task: 'click', resourcesType: 'ranges', resourcesId: obj.id, resourcesIdx: -1 };

            return { task: 'click', resourcesType: '', resourcesId: '', resourcesIdx: -1 };
        },
        checkVehicles(p, vehicles) {
            let rtn = null;
            if (!p || !vehicles || !vehicles.length) return rtn;
            if (this.vehiclesSelectable) {
                rtn = vehicles.find(v => {
                    if (!v.tunedPos || !v.modelExt) return false;
                    let s = v.modelExt.size,
                        r = Math.max(s.x, s.y) / 2;
                    return Expert.checkPointInCircle(v.tunedPos.x, v.tunedPos.y, r, p.x, p.y);
                });
            }
            return rtn;
        },
        checkPaths(p, paths) {
            let rtn = null;
            if (!p || !paths || !paths.length) return rtn;
            if (this.pathsSelectable) {
                rtn = this.$refs.pPaths.isPointInStroke(p);
            }
            console.warn('p-painter.checkPaths: ', rtn);
            return rtn;
        },
        // /**
        //  * 根据鼠标点击的位置，计算在子组件中是否点击到路径
        //  */
        // checkPathsByPoint(cursorPos, transPos) {
        //     // let rtn = this.$refs.pPaths.refresh(cursorPos);
        //     let rtn = this.$refs.pPaths.isPointInStroke(cursorPos, transPos);
        //     console.warn('p-painter.checkPathsByPoint: ', rtn);
        //     return rtn;
        // },
        checkContours(p, contours) {
            let rtn = null;
            if (!p || !contours || !contours.length) return rtn;
            // rtn = contours.find(v => {
            //     return Expert.checkPointInPolyline(p, v.points);
            // });
            // console.error(type, this.rangesSelectable, this.contoursSelectable);
            if (this.contoursSelectable) rtn = this.$refs.pContours.isPointInStroke(p, 'contours');
            console.warn('p-painter.checkContours: ', rtn);
            return rtn;
        },
        checkRanges(p, ranges) {
            let rtn = null;
            if (!p || !ranges || !ranges.length) return rtn;
            if (this.rangesSelectable) rtn = this.$refs.pContours.isPointInStroke(p, 'ranges');
            console.warn('p-painter.checkRanges: ', rtn);
            return rtn;
        },

        finallyClick(res) {
            console.log('p-painter.finallyClick: ', res.data);
            let typ = (res && res.data && res.data.resourcesType) || '',
                id = res.data.resourcesId,
                ids = [id],
                // whitch object's type was just selected
                isSelectedVehicle = typ === 'vehicles',
                // isSelectedPath = !!this.clickedPath,
                isSelectedPath = typ === 'paths',
                isSelectedContour = typ === 'contours',
                isSelectedRange = typ === 'ranges',
                // whitch object was just selected
                selectedVehicle = isSelectedVehicle ? this.selectedVehicles.indexOf(id) >= 0 : false,
                // selectedPath = isSelectedPath ? this.selectedPaths.indexOf(this.clickedPath.id) >= 0 : false,
                selectedPath = isSelectedPath ? this.selectedPaths.indexOf(id) >= 0 : false,
                selectedContour = isSelectedContour ? this.selectedContours.indexOf(id) >= 0 : false,
                selectedRange = isSelectedRange ? this.selectedRanges.indexOf(id) >= 0 : false,
                // whitch box is opening
                vehicleBoxOpened = this.vehiclesSelectable,
                pathBoxOpened = this.pathsSelectable,
                contourBoxOpened = this.contoursSelectable,
                rangeBoxOpened = this.rangesSelectable;
            // console.log('p-painter.finallyClick: ', isSelectedPath, selectedPath, pathBoxOpened);
            // console.log('p-painter.finallyClick: ', isSelectedPath, selectedPath, pathBoxOpened);
            if (vehicleBoxOpened && isSelectedVehicle && !selectedVehicle) {
                if (this.isAltFnActive) ids = ids.concat(this.selectedVehicles);
                this.$store.commit(enums.DESELECT_VEHICLES_ALL, ids);
                res.data.resourcesType = 'vehicles';
                res.data.resourcesId = id;
                // this.$emit('vehiclesChange', ids);
                this.emitChange('vehicles', ids);
            } else if (isSelectedVehicle && selectedVehicle) {
                this.$store.commit(enums.DESELECT_VEHICLES_ALL);
                res.data.resourcesType = 'vehicles';
                res.data.resourcesId = id;
                // this.$emit('vehiclesChange', []);
                this.emitChange('vehicles', []);
            } else if (pathBoxOpened && isSelectedPath && !selectedPath) {
                // id = this.clickedPath.id;
                // ids = [id];
                if (this.isAltFnActive) ids = ids.concat(this.selectedPaths);
                this.$store.commit(enums.DESELECT_PATHS_ALL, ids);
                res.data.resourcesType = 'paths';
                // res.data.resourcesId = this.clickedPath.id;
                res.data.resourcesId = id;
                // this.$emit('pathsChange', ids);
                this.emitChange('paths', ids);
            } else if (isSelectedPath && selectedPath) {
                this.$store.commit(enums.DESELECT_PATHS_ALL);
                res.data.resourcesType = 'paths';
                // res.data.resourcesId = this.clickedPath.id;
                res.data.resourcesId = id;
                // this.$emit('pathsChange', []);
                this.emitChange('paths', []);
            } else if (contourBoxOpened && isSelectedContour && !selectedContour) {
                if (this.isAltFnActive) ids = ids.concat(this.selectedContours);
                this.$store.commit(enums.DESELECT_CONTOURS_ALL, ids);
                res.data.resourcesType = 'contours';
                res.data.resourcesId = id;
                // this.$emit('contoursChange', ids);
                this.emitChange('contours', ids);
            } else if (isSelectedContour && selectedContour) {
                this.$store.commit(enums.DESELECT_CONTOURS_ALL);
                res.data.resourcesType = 'contours';
                res.data.resourcesId = id;
                // this.$emit('contoursChange', []);
                this.emitChange('contours', []);
            } else if (rangeBoxOpened && isSelectedRange && !selectedRange) {
                if (this.isAltFnActive) ids = ids.concat(this.selectedRanges);
                this.$store.commit(enums.DESELECT_RANGES_ALL, ids);
                res.data.resourcesType = 'ranges';
                res.data.resourcesId = id;
                // this.$emit('rangesChange', ids);
                this.emitChange('ranges', ids);
            } else if (isSelectedRange && selectedRange) {
                this.$store.commit(enums.DESELECT_RANGES_ALL);
                res.data.resourcesType = 'ranges';
                res.data.resourcesId = id;
                // this.$emit('rangesChange', []);
                this.emitChange('ranges', []);
            } else if (this.openedBoxes.length > 1) {
                // 未选中当前类型的资源 && 新增窗口
                console.log('--------------> ', this.selectedVehicles);
                // 车辆窗口下打开选择路径后不过清空处理
                // do nothing ...
            } else {
                this.$store.commit(enums.DESELECT_VEHICLES_ALL);
                this.emitChange('vehicles', []);
                this.$store.commit(enums.DESELECT_PATHS_ALL);
                this.emitChange('paths', []);
                this.$store.commit(enums.DESELECT_CONTOURS_ALL);
                this.emitChange('contours', []);
                this.$store.commit(enums.DESELECT_RANGES_ALL);
                this.emitChange('ranges', []);
            }
            if (!res || !res.data || !res.data.resourcesType || !res.data.resourcesId) return;
            console.log('p-painter.finallyClick: ', res.data);
            // Tell the kernelWorker, reorder the resources queue.
            // Kernel.getInstance().postMessage(res.data);
        },
        emitChange(modules, ids) {
            this.$emit(`${modules}Change`, ids);
        },
        /**
         * draw functions...
         */
        handleDrawContours(res) {
            // console.warn('p-painter.handleDrawContours: ', res);
            this.$emit('drawContours', res);
        },
        handleDrawRanges(res) {
            this.$emit('drawRanges', res);
        },
        handleDrawPaths(res) {
            this.$emit('drawPaths', res);
        },
        handleQuickJob(res) {
            this.$emit('quickJob', res);
        }
    }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<!-- <style scoped lang="scss"> -->
<style lang="scss">
.p-painter {
    position: relative;
    width: 100%;
    height: 100%;

    .v-canvas-grid,
    .p-painter-contours,
    .p-painter-paths,
    .p-painter-vehicles {
        position: absolute;
        left: 0;
        top: 0;
    }

    .debuger {
        min-width: 100px;
        position: absolute;
        top: 0;
        right: 0;
        background: rgba(255, 255, 255, 0.8);
        z-index: 9;
        border-radius: 3px;
        box-shadow: 0 0 5px #999;
        padding: 2px 6px;
        margin: 3px;
        font-size: 8px;
        line-height: 20px;
    }
}
</style>
